﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
using System.Windows;
using Caliburn.Micro;
using MefContainer;

namespace MvvmEx.Bootstrapper
{
    public class MefBootstrapper<T> : BootstrapperBase
    {
        #region 构造
        /// <summary>
        /// 构造
        /// </summary>
        public MefBootstrapper()
        {
            Initialize();
        }
        #endregion


        #region 保护方法
        protected override void Configure()
        {
            LogManager.GetLog = (type) => new DebugLog(type);

            CompositionBatch batch = new CompositionBatch();
            batch.AddExportedValue<IWindowManager>(new WindowManager());
            batch.AddExportedValue<IEventAggregator>(new EventAggregator());

            MefHelper.Compose(batch);
        }

        protected override IEnumerable<Assembly> SelectAssemblies()
        {
            var assemlibes = new List<Assembly>();

            assemlibes.AddRange(base.SelectAssemblies());

            MefHelper.Assemblies.ForEach(assembly =>
            {
                if (!assemlibes.Contains(assembly))
                {
                    assemlibes.Add(assembly);
                }
            });

            return assemlibes;
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return MefHelper.GetExportedValues<object>(AttributedModelServices.GetContractName(service));
        }

        protected override object GetInstance(Type service, string key)
        {
            var contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;

            var export = MefHelper.GetExportedValue<object>(contract);

            if (export != null)
            {
                return export;
            }
            else
            {
                throw new Exception("No Instace in MEF!");
            }
        }

        protected override void BuildUp(object instance)
        {
            MefHelper.SatisfyImportsOnce(instance);
        }

        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor<T>();
        }
        #endregion
    }
}